package jp.co.sansou.android.atnd.activity;

import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jp.co.sansou.android.asynctask.AsyncTaskProgressDialog;
import jp.co.sansou.android.asynctask.IAsyncTaskCallBack;
import jp.co.sansou.android.asynctask.IAsyncTaskDoInBackground;
import jp.co.sansou.android.atnd.R;
import jp.co.sansou.android.atnd.beans.AtndUsersBean;
import jp.co.sansou.android.atnd.beans.AtndUsersSubBean;
import jp.co.sansou.android.atnd.common.ImageAcquisition4URL;
import jp.co.sansou.android.atnd.db.AtndDao;
import jp.co.sansou.android.atnd.util.AtndEventSearch;
import jp.co.sansou.android.atnd.util.AtndUsersSearch;
import jp.co.sansou.android.atnd.util.JsonObj4List;
import net.sf.textile4j.Textile;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ViewFlipper;

public class ActAtndDetail extends Activity {

	private ViewFlipper vfpAtnd;

	private TextView tvwCount;

	private Button btnLeft;

	private Button btnRight;

	private ListView lvwUsers;

	private List<AtndUsersBean> listEvent;

	private List<AtndUsersSubBean> listUser;

	private int eventId;

	private int defaultCnt;
	private int count;

	private TwitterImage twitterImage = new TwitterImage();

	private final int MENU_DEFAULT_USER_PLUS = 0;
	private final int MENU_USER_ADD = 1;

	/** フリックにより画面遷移する為のX座標保持変数 */
	private float lastTouchX;

	private View.OnClickListener lsnrBtnFlipper = new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btn_left:
				showPrevious();
				break;
			case R.id.btn_right:
				showNext();
				break;
			default:
				break;
			}
		}
	};

	private void showNext() {
		vfpAtnd.setInAnimation(AnimationUtils.loadAnimation(this,
				R.anim.move_in_right));
		vfpAtnd.setOutAnimation(AnimationUtils.loadAnimation(this,
				R.anim.move_out_left));
		vfpAtnd.showNext();
	}

	private void showPrevious() {
		vfpAtnd.setInAnimation(AnimationUtils.loadAnimation(this,
				R.anim.move_in_left));
		vfpAtnd.setOutAnimation(AnimationUtils.loadAnimation(this,
				R.anim.move_out_right));
		vfpAtnd.showPrevious();
	}

	private View.OnTouchListener lsnrFlickViewFlipper = new View.OnTouchListener() {
		@Override
		public boolean onTouch(View view, MotionEvent motionevent) {
			switch (motionevent.getAction()) {
			case MotionEvent.ACTION_DOWN:
				lastTouchX = motionevent.getX();
				break;
			case MotionEvent.ACTION_UP:
				float currentX = motionevent.getX();
				if (lastTouchX < currentX && (currentX - lastTouchX) >= 100) {
					showPrevious();
				}
				if (lastTouchX > currentX && (lastTouchX - currentX) >= 100) {
					showNext();
				}
				break;
			}
			return true;
		}

	};

	private AdapterView.OnItemClickListener lsnrItemClick = new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> adapterview, View view, int i,
				long l) {

			final AtndUsersSubBean bean = listUser.get(i);
			if (bean.isAccepted()) {
				AlertDialog.Builder alertDialog = new AlertDialog.Builder(
						ActAtndDetail.this);
				alertDialog.setTitle("確認メッセージ");
				alertDialog.setMessage(bean.getNickname()
						+ " さん\nこのイベントをキャンセルしますか？");
				alertDialog.setPositiveButton("はい",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int whichButton) {
								boolean result = delUserEntry(bean.getUserId());
								if (result) {
									count--;
									dispCurrentCnt();
									bean.setAccepted(false);
								} else {
									bean.setAccepted(true);
								}
								notifyDataSetChanged();
							}
						});
				alertDialog.setNegativeButton("いいえ", null);
				alertDialog.create();
				alertDialog.show();
			} else {
				AlertDialog.Builder alertDialog = new AlertDialog.Builder(
						ActAtndDetail.this);
				alertDialog.setTitle("確認メッセージ");
				alertDialog.setMessage(bean.getNickname()
						+ " さん\nこのイベントに参加しますか？");
				alertDialog.setPositiveButton("はい",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int whichButton) {
								boolean result = regUserEntry(bean);
								if (result) {
									count++;
									dispCurrentCnt();
									bean.setAccepted(true);
								} else {
									bean.setAccepted(false);
								}
								notifyDataSetChanged();
							}
						});
				alertDialog.setNegativeButton("いいえ", null);
				alertDialog.create();
				alertDialog.show();
			}
		}
	};

	private void dispCurrentCnt() {
		tvwCount.setText("現在 : " + (count + defaultCnt) + " 人");
	}

	@SuppressWarnings("unchecked")
	private void notifyDataSetChanged() {
		((ArrayAdapter<AtndUsersSubBean>) lvwUsers.getAdapter())
				.notifyDataSetChanged();
	}

	private boolean regUserEntry(AtndUsersSubBean bean) {
		AtndDao dao = new AtndDao(this);
		return dao.regUserEntry(bean, eventId);
	}

	private boolean delUserEntry(int userId) {
		AtndDao dao = new AtndDao(this);
		return dao.delUserEntry(eventId, userId);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.atnd_detail);

		vfpAtnd = (ViewFlipper) findViewById(R.id.vfp_atnd);
		tvwCount = (TextView) findViewById(R.id.tvw_count);
		btnLeft = (Button) findViewById(R.id.btn_left);
		btnRight = (Button) findViewById(R.id.btn_right);
		lvwUsers = (ListView) findViewById(R.id.lvw_users);

		btnLeft.setOnClickListener(lsnrBtnFlipper);
		btnRight.setOnClickListener(lsnrBtnFlipper);
		vfpAtnd.setOnTouchListener(lsnrFlickViewFlipper);
		lvwUsers.setOnItemClickListener(lsnrItemClick);

		setDispInfo();
	}

	private void setDispInfo() {


		Bundle param = getIntent().getExtras();

		eventId = param.getInt(AtndEventSearch.AtndEventJsonSubKeys.EVENT_ID
				.name());

		AtndDao dao = new AtndDao(this);
		defaultCnt = dao.getDefaultCnt(eventId);

		/* +*+* ATND 参加者（ユーザ）一覧 +*+* */
		AsyncTaskProgressDialog asyncTaskProgressDialog = new AsyncTaskProgressDialog(
				this, getResources().getString(R.string.msg_progress_wait),
				asyncTaskDoInBackground, asyncTaskCallBack);

		asyncTaskProgressDialog.execute();

		/* +*+* ATND詳細情報 +*+* */

		((TextView) findViewById(R.id.tvw_title)).setText(param
				.getString(AtndEventSearch.AtndEventJsonSubKeys.TITLE.name()));

		((TextView) findViewById(R.id.tvw_started_at)).setText(param
				.getString(AtndEventSearch.AtndEventJsonSubKeys.STARTED_AT
						.name()));

		((TextView) findViewById(R.id.tvw_ended_at))
				.setText(param
						.getString(AtndEventSearch.AtndEventJsonSubKeys.ENDED_AT
								.name()));

		((TextView) findViewById(R.id.tvw_limit)).setText(param
				.getString(AtndEventSearch.AtndEventJsonSubKeys.LIMIT.name()));

		((TextView) findViewById(R.id.tvw_place)).setText(param
				.getString(AtndEventSearch.AtndEventJsonSubKeys.PLACE.name()));

		((TextView) findViewById(R.id.tvw_url)).setText(param
				.getString(AtndEventSearch.AtndEventJsonSubKeys.URL.name()));

		((TextView) findViewById(R.id.tvw_owner_nickname)).setText(param
				.getString(AtndEventSearch.AtndEventJsonSubKeys.OWNER_NICKNAME
						.name()));

		/* +*+* ATND フリー入力エリア（textile部分）+*+* */
		Textile t = new Textile();
		String description = param
				.getString(AtndEventSearch.AtndEventJsonSubKeys.DESCRIPTION
						.name());
		if (!StringUtils.isEmpty(description)) {
			String html = t.process(description);

			WebView wbvAtnd = (WebView) findViewById(R.id.wbv_atnd);

			// 以下だと文字化けが発生
			// wbvAtnd.loadData(html, "text/html", "utf-8");

			// 以下に修正すると文字化けがなくなり無事表示できた。
			// どうして？？
			wbvAtnd.loadDataWithBaseURL("about:blank", html, "text/html",
					"UTF-8", null);

			wbvAtnd.getSettings().setBuiltInZoomControls(true);
		}
	}

	private IAsyncTaskDoInBackground asyncTaskDoInBackground = new IAsyncTaskDoInBackground() {
		@Override
		public void doInBackground() {

			// ATNDのイベントIDからATNDの最新情報を取得します。
			AtndUsersSearch.Builder builder = new AtndUsersSearch.Builder();
			builder.eventId(eventId);
			AtndUsersSearch atndUsersSearch = builder.build();
			JSONObject json = atndUsersSearch.searchUsersResultJson();

			try {
				listEvent = JsonObj4List.getUsersList(json);
				if (listEvent != null && listEvent.size() > 0) {
					AtndUsersBean bean = listEvent.get(0);
					listUser = bean.getUsers();

					// 参加登録済みのユーザを取得します。
					AtndDao dao = new AtndDao(ActAtndDetail.this);
					List<Integer> entriedUserIds = dao
							.getEntriedUserIds(eventId);
					if (entriedUserIds.size() > 0) {
						for (AtndUsersSubBean subBean : listUser) {
							if (entriedUserIds.contains(subBean.getUserId())) {
								subBean.setAccepted(true);
							}
						}
					}
					count = entriedUserIds.size();
				}
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
	};

	private IAsyncTaskCallBack asyncTaskCallBack = new IAsyncTaskCallBack() {
		@Override
		public void doInBackgroundCallBack() {
			if (listUser != null) {
				lvwUsers.setAdapter(new OrgListAdapter(ActAtndDetail.this,
						listUser));
				dispCurrentCnt();
			}
		}
	};

	/**
	 * ATND参加者（ユーザ）検索結果のリストに設定する独自Adapterクラスです。
	 *
	 * @author SANSOU SYSTEMS Co.
	 */
	private class OrgListAdapter extends ArrayAdapter<AtndUsersSubBean> {
		private LayoutInflater mInflater;

		public OrgListAdapter(Context context, List<AtndUsersSubBean> listDaily) {
			super(context, 0, listDaily);
			this.mInflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		public View getView(final int position, View convertView,
				ViewGroup parent) {

			if (convertView == null) {
				convertView = mInflater.inflate(R.layout.atnd_users_list_row,
						null);
			}
			AtndUsersSubBean item = this.getItem(position);

			if (item != null) {
				ImageView imvTwitterIcon = (ImageView) convertView
						.findViewById(R.id.imv_twitter_icon);
				TextView tvwNickName = (TextView) convertView
						.findViewById(R.id.tvw_nickname);
				TextView tvwTwitterId = (TextView) convertView
						.findViewById(R.id.tvw_twitter_id);
				TextView tvwStatus = (TextView) convertView
						.findViewById(R.id.tvw_status);
				ImageView imvSumi = (ImageView) convertView
						.findViewById(R.id.imv_sumi);

				if (StringUtils.isEmpty(item.getTwitterImg())) {
					// +*+*+*+* このsetImageBitmap(null);を入れないと画像が変な事になる +*+*+*+*
					imvTwitterIcon.setImageBitmap(null);
				} else {
					imvTwitterIcon.setTag(item.getTwitterId());
					AsyncTaskTwitterImage task = new AsyncTaskTwitterImage(
							imvTwitterIcon);
					task.execute(item.getTwitterImg());
				}

				tvwNickName.setText(item.getNickname());
				String twitterId = item.getTwitterId();
				if (twitterId == null) {
					twitterId = "";
				}
				tvwTwitterId.setText(twitterId);
				if (item.getStatus() == 1) {
					tvwStatus.setText("参加");
				} else {
					tvwStatus.setText("補欠");
				}

				if (item.isAccepted()) {
					imvSumi.setVisibility(View.VISIBLE);
				} else {
					imvSumi.setVisibility(View.GONE);
				}
			}

			return convertView;
		}

		private class AsyncTaskTwitterImage extends
				AsyncTask<String, Void, Bitmap> {

			private ImageView image;

			private String tag;

			public AsyncTaskTwitterImage(ImageView image) {
				this.image = image;
				this.tag = (String) image.getTag();
			}

			@Override
			protected Bitmap doInBackground(String... params) {
				Bitmap image = twitterImage.getImage(params[0]);
				if (image == null) {
					ImageAcquisition4URL img4url = new ImageAcquisition4URL();
					try {
						image = img4url.getImage(params[0]);
					} catch (ClientProtocolException e) {
						image = null;
						e.printStackTrace();
					} catch (IOException e) {
						image = null;
						e.printStackTrace();
					}
					twitterImage.setImage(params[0], image);
				}
				return image;
			}

			@Override
			protected void onPostExecute(Bitmap result) {
				if (tag.equals(image.getTag())) {
					image.setImageBitmap(result);
				}
			}
		}
	}

	/**
	 * Twitterアイコンのイメージ画像を管理するクラスです。
	 *
	 * @author s220484
	 */
	private class TwitterImage {
		private Map<String, Bitmap> imageMap = new HashMap<String, Bitmap>();

		public Bitmap getImage(String key) {
			if (imageMap.containsKey(key)) {
				return imageMap.get(key);
			}
			return null;
		}

		public void setImage(String key, Bitmap image) {
			imageMap.put(key, image);
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {

		// 現在表示されている画面がユーザ一覧かどうか
		boolean isUserListCurrent = vfpAtnd.getCurrentView().getId() == R.id.inc_detail_3;

		// 押下されたボタンが「menu」ボタンかどうか
		boolean isKeycodeMenu = keyCode == KeyEvent.KEYCODE_MENU;

		if (!isUserListCurrent && isKeycodeMenu) {
			return true;
		} else {
			// super.onKeyDownを実行しないとほかのボタン押下イベントが実行されない
			return super.onKeyDown(keyCode, event);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENU_DEFAULT_USER_PLUS, 0, "デフォルト参加者").setIcon(
				android.R.drawable.ic_input_add);
		menu.add(0, MENU_USER_ADD, 1, "参加者").setIcon(
				android.R.drawable.ic_input_add);

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case MENU_DEFAULT_USER_PLUS:
			setDefaultUserCnt();
			break;
		case MENU_USER_ADD:
			addUser();
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void addUser() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("参加登録");
		builder.setMessage("お名前（アカウント名可）を入力して下さい。");

		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		final View dialogView = inflater
				.inflate(R.layout.dialog_add_user,
				null);
		final EditText edt = (EditText) dialogView
				.findViewById(R.id.edt_add_user_name);

		builder.setView(dialogView);
		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (which == DialogInterface.BUTTON1) {
					String name = edt.getText().toString();
					addUser(name);
				}
			}
		});

		final AlertDialog dialog = builder.create();

		edt.setOnEditorActionListener(new TextView.OnEditorActionListener() {

			@Override
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if (event != null
						&& event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
					String name = edt.getText().toString();
					addUser(name);
					dialog.dismiss();
				}
				return false;
			}
		});

		dialog.show();
	}

	private void addUser(String name) {
		AtndUsersSubBean bean = new AtndUsersSubBean();
		bean.setAccepted(true);
		bean.setNickname(name);
		bean.setStatus(1);

		listUser.add(bean);

		regUserEntry(bean);
	}

	private void setDefaultUserCnt() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("デフォルト参加者の設定");
		builder.setMessage("デフォルトで追加する人数を入力して下さい。");

		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		final View dialogView = inflater.inflate(R.layout.dialog_add_user_cnt,
				null);
		final EditText edt = (EditText) dialogView
				.findViewById(R.id.edt_add_user_cnt);
		edt.setText(String.valueOf(defaultCnt));


		builder.setView(dialogView);
		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (which == DialogInterface.BUTTON1) {
					String cnt = edt.getText().toString();
					if (StringUtils.isNumeric(cnt)) {
						defaultCnt = NumberUtils.toInt(cnt);
						updDefaultCnt();
						dispCurrentCnt();
					}
				}
			}
		});

		final AlertDialog dialog = builder.create();

		edt.setOnEditorActionListener(new TextView.OnEditorActionListener() {

			@Override
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				if (event != null
						&& event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
					String cnt = edt.getText().toString();
					if (StringUtils.isNumeric(cnt)) {
						defaultCnt = NumberUtils.toInt(cnt);
						updDefaultCnt();
						dispCurrentCnt();
					}
					dialog.dismiss();

				}
				return false;
			}
		});

		dialog.show();
	}

	private void updDefaultCnt() {
		AtndDao dao = new AtndDao(this);
		dao.updDefaultCnt(eventId, defaultCnt);
	}
}
